/*
 * DefaultComboBoxModel.java  0.4.0 / Oct 26, 2010
 *
 * Copyright (c) 2010 - 2011, cute4j.com and contributors.
 *
 * This software is licensed under the LGPL version 2.1 license.
 * A copy of this license is included in the file LICENSE-LGPL.txt.
 */
package com.cute4j.swing;

import java.util.ArrayList;
import java.util.Vector;

import com.cute4j.swing.list.AbstractListModel;

/**
 * Default ComboBox Model.
 *
 * @author Slobodan Vrkacevic
 * @version 0.4.0
 */
public class DefaultComboBoxModel extends AbstractListModel
                                  implements MutableComboBoxModel {

// Protected Fields. -----------------------------------------------------------

  protected ArrayList items;
  protected Object selectedItem;

// Public Constructors. --------------------------------------------------------

  /**
   * Constructs new DefaultComboBoxModel object.
   *
   * @param objects the objects
   */
  public DefaultComboBoxModel(final Object[] objects) {
    if (objects == null) {
      throw new IllegalArgumentException("Null objects");
    }
    int ol = objects.length;
    items = new ArrayList(ol);
    for (int i = 0; i < ol; i++) {
      items.add(objects[i]);
    }
    if (ol > 0) {
      selectedItem = objects[0];
    }
  }

  /**
   * Constructs new DefaultComboBoxModel object.
   *
   * @param vector the vector
   */
  public DefaultComboBoxModel(final Vector vector) { // NOPMD
    if (vector == null) {
      throw new IllegalArgumentException("Null vector");
    }
    items = new ArrayList(vector);
    if (vector.size() > 0) {
      selectedItem = vector.get(0);
    }
  }

  /**
   * Constructs new DefaultComboBoxModel object.
   *
   * @param items the items
   */
  public DefaultComboBoxModel(final ArrayList items) {
    if (items == null) {
      throw new IllegalArgumentException("Null items");
    }
    this.items = items;
    if (items.size() > 0) {
      selectedItem = items.get(0);
    }
  }

  /**
   * Constructs new DefaultComboBoxModel object.
   */
  public DefaultComboBoxModel() {
    items = new ArrayList();
  }

// Public Methods. -------------------------------------------------------------

  /**
   * Returns the index of the specified element.
   *
   * @param object the element
   *
   * @return the index of the specified element
   */
  public final int getIndexOf(final Object object) {
    return items.indexOf(object);
  }

  /**
   * Removes all elements.
   */
  public final void removeAllElements() {
    int size = items.size();
    if (size > 0) {
      selectedItem = null;
      items.clear();
      fireIntervalRemoved(this, 0, size - 1);
    }
  }

// MutableComboBoxModel Implementation. ----------------------------------------

  /**
   * {@inheritDoc}
   */
  public final int getSize() {
    return items.size();
  }

  /**
   * {@inheritDoc}
   */
  public final Object getElementAt(final int index) {
    if ((index >= 0) && (index < items.size())) {
      return items.get(index);
    }
    return null;
  }

  /**
   * {@inheritDoc}
   */
  public final void addElement(final Object object) {
    items.add(object);
    int ci = items.size() - 1;
    fireIntervalAdded(this, ci, ci);
    if (ci == 0) {
      setSelectedItem(object);
    }
  }

  /**
   * {@inheritDoc}
   */
  public final void insertElementAt(final Object object, final int index) {
    items.add(index, object);
    fireIntervalAdded(this, index, index);
  }

  /**
   * {@inheritDoc}
   */
  public final void removeElementAt(final int index) {
    Object removedItem = items.remove(index);
    if (removedItem == selectedItem) { // NOPMD
      if (index == 0) {
        selectedItem = items.get(0);
      } else {
        selectedItem = items.get(index - 1);
      }
    }
    fireIntervalRemoved(this, index, index);
  }

  /**
   * {@inheritDoc}
   */
  public final void removeElement(final Object object) {
    int index = items.indexOf(object);
    if (index != -1) {
      removeElementAt(index);
    }
  }

  /**
   * {@inheritDoc}
   */
  public final Object getSelectedItem() {
    return selectedItem;
  }

  /**
   * {@inheritDoc}
   */
  public final void setSelectedItem(Object item) {
    if (selectedItem == null) {
      if (item == null) {
         return;
      }
    } else {
      if (selectedItem.equals(item)) {
        return;
      }
    }
    selectedItem = item;
    fireContentsChanged(this, -1, -1);
  }

}
